﻿using Microsoft.Win32.SafeHandles;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;

namespace BarcodePrint
{
    public class PrintWithLPT
    {
        private string _portName;
        /// <summary>
        /// LPT 端口号
        /// </summary>
        public Int32 Port { get; set; }

        public PrintWithLPT(int port)
        {
            this.Port = port;
            this._portName = string.Format("LPT{0}", port == 0 ? 1 : port);
        }
        public PrintWithLPT() : this(1) { }

        public bool Print(string cmd)
        {
            byte[] bytes = Encoding.Default.GetBytes(cmd);
            return LPTAccess.Write(this._portName, bytes);
        }

        public bool Print(byte[] bytes)
        {
            return LPTAccess.Write(this._portName, bytes);
        }
    }

    internal class LPTAccess
    {
        private const short FILE_ATTRIBUTE_NORMAL = 0x80;
        private const short INVALID_HANDLE_VALUE = -1;
        private const uint GENERIC_READ = 0x80000000;
        private const uint GENERIC_WRITE = 0x40000000;
        private const uint CREATE_NEW = 1;
        private const uint CREATE_ALWAYS = 2;
        private const uint OPEN_EXISTING = 3;

        [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)]
        private static extern SafeFileHandle CreateFile(
            string strFileName,
            uint dwDesiredAccess,
            uint dwShareMode,
            IntPtr intptrSecurityAttributes,
            uint dwCreationDisposition,
            uint dwFlagsAndAttributes,
            IntPtr intptrTemplateFile);

        public static bool Write(string portName, string cmdText)
        {
            return Write(portName, System.Text.Encoding.UTF8.GetBytes(cmdText));
        }

        public static bool Write(string portName, byte[] cmdBytes)
        {
            bool result = false;
            FileStream fileStream = null;
            SafeFileHandle handle = null;
            try
            {
                handle = CreateFile(portName, GENERIC_READ | GENERIC_WRITE, 0, IntPtr.Zero, OPEN_EXISTING, 0, IntPtr.Zero);
                if (!handle.IsInvalid)
                {
                    fileStream = new FileStream(handle, FileAccess.Write);
                    fileStream.Write(cmdBytes, 0, cmdBytes.Length);
                    result = true;
                }
            }
            catch (Exception ex)
            {
                throw new Exception(ex.Message, ex);
            }
            finally
            {
                if (fileStream != null)
                {
                    fileStream.Close();
                    fileStream.Dispose();
                    fileStream = null;
                }
                if (handle != null)
                {
                    handle.Close();
                    handle.Dispose();
                    handle = null;
                }
            }
            return result;
        }
    }
}
